package com.eye.catcher.service.generate.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.eye.catcher.common.RedisUtils;
import com.eye.catcher.constants.RedisConstants;
import com.eye.catcher.constants.SbCode;
import com.eye.catcher.entity.TYwDaBaseInfo;
import com.eye.catcher.entity.TYwDaFieldInfo;
import com.eye.catcher.mapper.TYwDaFieldInfoMapper;
import com.eye.catcher.service.generate.ITYwDaBaseInfoService;
import com.eye.catcher.service.generate.ITYwDaFieldInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.eye.catcher.system.role.param.RoleDto;
import com.eye.catcher.system.user.param.UserLoginInfo;
import com.eye.catcher.system.yw.Info.param.FieldInfoDto;
import com.eye.catcher.system.yw.Info.param.FieldInfoPage;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 田地 信息 表 服务实现类
 * </p>
 *
 * @author huzhiwei
 * @since 2022-05-12
 */
@Slf4j
@Service
public class TYwDaFieldInfoServiceImpl extends ServiceImpl<TYwDaFieldInfoMapper, TYwDaFieldInfo> implements ITYwDaFieldInfoService {
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private ITYwDaBaseInfoService baseInfoService;
    @Autowired
    private TYwDaFieldInfoMapper fieldInfoMapper;

    @Value("${base.all-permissions.roleId}")
    private String baseAllPermissionsRoleId;

    @Override
    public void addFieldInfo(TYwDaFieldInfo info) {
        UserLoginInfo userLoginInfo = (UserLoginInfo)redisUtils.get(RedisConstants.USER_INFO_EXPIRE.getKey()+info.getCreateUserId());
        info.setCreateUserId(info.getCreateUserId());
        info.setCreateUserName(userLoginInfo.getUserDto().getUserName());
        info.setCreateLoginName(userLoginInfo.getUserDto().getLoginName());
        info.setCreateTime(LocalDateTime.now());
        info.setSource(SbCode.DATA_SOURCE_CREATE.getCode());
        if(null != info.getBaseId()){
            TYwDaBaseInfo baseInfo = baseInfoService.getById(info.getBaseId());
            if(null != baseInfo) {
                info.setBaseCode(baseInfo.getBaseCode());
                info.setBaseName(baseInfo.getBaseName());
            }
        }
        this.save(info);
    }

    @Override
    public void editFieldInfo(TYwDaFieldInfo info) {
        UserLoginInfo userLoginInfo = (UserLoginInfo)redisUtils.get(RedisConstants.USER_INFO_EXPIRE.getKey()+info.getUpdateUserId());
        info.setUpdateUserId(info.getCreateUserId());
        info.setUpdateUserName(userLoginInfo.getUserDto().getUserName());
        info.setUpdateLoginName(userLoginInfo.getUserDto().getLoginName());
        info.setUpdateTime(LocalDateTime.now());
        if(null != info.getBaseId()){
            TYwDaBaseInfo baseInfo = baseInfoService.getById(info.getBaseId());
            if(null != baseInfo) {
                info.setBaseCode(baseInfo.getBaseCode());
                info.setBaseName(baseInfo.getBaseName());
            }
        }
        this.updateById(info);
    }

    @Override
    public void deleteByIds(String ids) {
        this.removeByIds(Arrays.asList(ids.split(",")));
    }

    @Override
    public Object getAllList(FieldInfoDto fieldInfo) {
        QueryWrapper<TYwDaFieldInfo> wrapper = Wrappers.query();
        //组装查询条件
        this.appendWrapper(wrapper,fieldInfo);

        wrapper.orderByAsc(" BASE_ID,SORT_NO,FIELD_CODE ");
        return fieldInfoMapper.list(wrapper);
    }

    @Override
    public Object getPageList(FieldInfoPage fieldInfoPage) {
        Page<TYwDaFieldInfo> page=new Page<>(fieldInfoPage.getPage().getPageNum(),fieldInfoPage.getPage().getPageSize());
        QueryWrapper<TYwDaFieldInfo> wrapper = Wrappers.query();
        //组装查询条件
        this.appendWrapper(wrapper,fieldInfoPage.getFieldInfo());

        wrapper.orderByAsc(" BASE_ID,SORT_NO,FIELD_CODE ");
        //list
        IPage<TYwDaFieldInfo> returnPage = fieldInfoMapper.page(page, wrapper);
        //总数
        returnPage.setTotal(this.count(wrapper));
        return returnPage;
    }

    @Override
    public String export(String userId, HttpServletRequest request, HttpServletResponse response) {
        FieldInfoDto fieldInfo = new FieldInfoDto();
        fieldInfo.setUserId(userId);
        QueryWrapper<TYwDaFieldInfo> wrapper = Wrappers.query();
        //组装查询条件
        this.appendWrapper(wrapper,fieldInfo);
        wrapper.orderByAsc(" BASE_ID,SORT_NO ");
        List<TYwDaFieldInfo> list =  fieldInfoMapper.list(wrapper);
        Iterator it=list.iterator();
        ByteArrayOutputStream baos=null;
        try{
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
            String s = sdf.format(new Date());
            XSSFWorkbook workbook = new XSSFWorkbook();
            XSSFSheet sheet = workbook.createSheet("田地列表");
            XSSFRow row = sheet.createRow((short) 0);
            XSSFCell cell = null;
            cell = row.createCell((short) 0);
            cell.setCellValue("序号");
            cell = row.createCell((short) 1);
            cell.setCellValue("田地编号");
            sheet.setColumnWidth(1, 25*256);
            cell = row.createCell((short) 2);
            cell.setCellValue("田地名称");
            sheet.setColumnWidth(2, 25*256);
            cell = row.createCell((short) 3);
            cell.setCellValue("所属基地");
            sheet.setColumnWidth(3, 25*256);
            cell = row.createCell((short) 4);
            cell.setCellValue("GPS经度");
            sheet.setColumnWidth(4, 25*256);
            cell = row.createCell((short) 5);
            cell.setCellValue("GPS纬度");
            sheet.setColumnWidth(5, 25*256);
            cell = row.createCell((short) 6);
            cell.setCellValue("土壤类型");
            sheet.setColumnWidth(6, 25*256);
            cell = row.createCell((short) 7);
            cell.setCellValue("土壤属性ph值");
            sheet.setColumnWidth(7, 25*256);
            cell = row.createCell((short) 8);
            cell.setCellValue("土壤属性n值");
            sheet.setColumnWidth(8, 25*256);
            cell = row.createCell((short) 9);
            cell.setCellValue("土壤属性p值");
            sheet.setColumnWidth(9, 25*256);
            cell = row.createCell((short) 10);
            cell.setCellValue("土壤属性om值");
            sheet.setColumnWidth(10, 25*256);
            cell = row.createCell((short) 11);
            cell.setCellValue("土壤属性k值");
            sheet.setColumnWidth(11, 25*256);
            cell = row.createCell((short) 12);
            cell.setCellValue("土壤墒情");
            sheet.setColumnWidth(12, 25*256);
            cell = row.createCell((short) 13);
            cell.setCellValue("茬口");
            sheet.setColumnWidth(13, 25*256);
            cell = row.createCell((short) 14);
            cell.setCellValue("品种");
            sheet.setColumnWidth(14, 25*256);
            cell = row.createCell((short) 15);
            cell.setCellValue("种子处理");
            sheet.setColumnWidth(15, 25*256);
            cell = row.createCell((short) 16);
            cell.setCellValue("秸秆还田深度");
            sheet.setColumnWidth(16, 25*256);
            cell = row.createCell((short) 17);
            cell.setCellValue("播期");
            sheet.setColumnWidth(17, 25*256);
            cell = row.createCell((short) 18);
            cell.setCellValue("播量");
            sheet.setColumnWidth(18, 25*256);
            cell = row.createCell((short) 19);
            cell.setCellValue("播种方式");
            sheet.setColumnWidth(19, 25*256);
            cell = row.createCell((short) 20);
            cell.setCellValue("施肥情况");
            sheet.setColumnWidth(20, 25*256);
            cell = row.createCell((short) 21);
            cell.setCellValue("播深");
            sheet.setColumnWidth(21, 25*256);
            cell = row.createCell((short) 22);
            cell.setCellValue("沟距");
            sheet.setColumnWidth(22, 25*256);
            cell = row.createCell((short) 23);
            cell.setCellValue("沟深");
            sheet.setColumnWidth(23, 25*256);
            cell = row.createCell((short) 24);
            cell.setCellValue("封闭化除用药");
            sheet.setColumnWidth(24, 25*256);
            cell = row.createCell((short) 25);
            cell.setCellValue("封闭化除时间");
            sheet.setColumnWidth(25, 25*256);
            cell = row.createCell((short) 26);
            cell.setCellValue("出苗期");
            sheet.setColumnWidth(26, 25*256);
            cell = row.createCell((short) 27);
            cell.setCellValue("基本苗");
            sheet.setColumnWidth(27, 25*256);
            cell = row.createCell((short) 28);
            cell.setCellValue("出苗方式");
            sheet.setColumnWidth(28, 25*256);
            cell = row.createCell((short) 29);
            cell.setCellValue("化除用药");
            sheet.setColumnWidth(29, 25*256);
            cell = row.createCell((short) 30);
            cell.setCellValue("化除用药时间");
            sheet.setColumnWidth(30, 25*256);

//            Object obj = redisUtils.hget("t_cod_ada_dictionary", "t_cod_da_file_status");
            int i=0;
            while(it.hasNext()){
                TYwDaFieldInfo detailInfo=(TYwDaFieldInfo)it.next();

                row=sheet.createRow((int)i+1);
                row.createCell((short) 0).setCellValue(i + 1);
                this.setCellValue(row,1,detailInfo.getFieldCode());
                this.setCellValue(row,2,detailInfo.getFieldName());
                this.setCellValue(row,3,detailInfo.getBaseName());
                this.setCellValue(row,4,detailInfo.getGpsLongitude());
                this.setCellValue(row,5,detailInfo.getGpsLatitude());
                this.setCellValue(row,6,detailInfo.getSoilType());
                this.setCellValue(row,7,detailInfo.getAttributePh());
                this.setCellValue(row,8,detailInfo.getAttributeN());
                this.setCellValue(row,9,detailInfo.getAttributeP());
                this.setCellValue(row,10,detailInfo.getAttributeOm());
                this.setCellValue(row,11,detailInfo.getAttributeK());
                this.setCellValue(row,12,detailInfo.getSoilMoisture());
                this.setCellValue(row,13,detailInfo.getCrop());
                this.setCellValue(row,14,detailInfo.getVarieties());
                this.setCellValue(row,15,detailInfo.getSeedTreatment());
                this.setCellValue(row,16,detailInfo.getStrawReturningDepth());
                this.setCellValue(row,17,
                        null != detailInfo.getSowingDate()?String.valueOf(detailInfo.getSowingDate()):"");
                this.setCellValue(row,18,detailInfo.getSowingQuantity());
                this.setCellValue(row,19,detailInfo.getSeedProcessing());
                this.setCellValue(row,20,detailInfo.getFertilizationConditions());
                this.setCellValue(row,21,detailInfo.getSowingDepth());
                this.setCellValue(row,22,detailInfo.getGrooveSpacing());
                this.setCellValue(row,23,detailInfo.getGrooveDepth());
                this.setCellValue(row,24,detailInfo.getBlockingRemovingDrugs());
                this.setCellValue(row,25,
                        null != detailInfo.getBlockingRemoveDate()?String.valueOf(detailInfo.getBlockingRemoveDate()):"");
                this.setCellValue(row,26,
                        null != detailInfo.getSeedlingStage()?String.valueOf(detailInfo.getSeedlingStage()):"");
                this.setCellValue(row,27,detailInfo.getBasicSeedling());
                this.setCellValue(row,28,detailInfo.getEmergenceWay());
                this.setCellValue(row,29,detailInfo.getEliminateDrugs());
                this.setCellValue(row,30,
                        null != detailInfo.getEliminateDrugsDate()?String.valueOf(detailInfo.getEliminateDrugsDate()):"");
                i++;
            }
            String filename = "田地列表" + s + ".xlsx";
            baos = new ByteArrayOutputStream();
            workbook.write(baos);
            byte[] getData = baos.toByteArray();
            baos.write(getData);
            if(getData.length != 0){
                response.setCharacterEncoding("utf-8");
                response.setContentType("application/x-msdownload;charset=utf-8");
                response.setContentLength(getData.length);
                response.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(filename,"UTF-8"));
                response.getOutputStream().write(getData,0,getData.length);
            }else{
                response.setHeader("MsgError","404");
            }
            response.getOutputStream().flush();
            response.getOutputStream().close();

        }
        catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(null != baos){
                try {
                    baos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return null;
    }

    private void setCellValue(XSSFRow row, int i, String value) {
        row.createCell((short) i).setCellValue(value==null?"":value);
    }
    private void appendWrapper(QueryWrapper<TYwDaFieldInfo> wrapper, FieldInfoDto fieldInfo) {

        if(StringUtils.isNotEmpty(fieldInfo.getId())){
            wrapper.eq("ID",Integer.parseInt(fieldInfo.getId()));
        }
        if(StringUtils.isNotEmpty(fieldInfo.getFieldCode())){
            wrapper.eq("FIELD_CODE",fieldInfo.getFieldCode());
        }
        if(StringUtils.isNotEmpty(fieldInfo.getFieldName())){
            wrapper.like("FIELD_NAME",fieldInfo.getFieldName());
        }
        if(StringUtils.isNotEmpty(fieldInfo.getBaseId())){
            wrapper.eq("BASE_ID",Integer.parseInt(fieldInfo.getBaseId()));
        }
        if(StringUtils.isNotEmpty(fieldInfo.getBaseCode())){
            wrapper.eq("BASE_CODE",fieldInfo.getBaseCode());
        }
        if(StringUtils.isNotEmpty(fieldInfo.getBaseName())){
            wrapper.like("BASE_NAME",fieldInfo.getBaseName());
        }
        if(StringUtils.isNotEmpty(fieldInfo.getCreateUserId())){
            wrapper.eq("CREATE_USER_ID",fieldInfo.getCreateUserId());
        }
        if(StringUtils.isNotEmpty(fieldInfo.getUserId())){
            UserLoginInfo userLoginInfo = (UserLoginInfo)redisUtils.get(RedisConstants.USER_INFO_EXPIRE.getKey()+fieldInfo.getUserId());
            if(!"admin".equals(userLoginInfo.getUserDto().getLoginName())){
                Set<String> rolesSet =new HashSet<>(
                        userLoginInfo.getRoleDtoList().stream().map(RoleDto::getId).collect(Collectors.toList())
                );
                if(!rolesSet.contains(baseAllPermissionsRoleId)){
                    wrapper.eq("BASE_ID",userLoginInfo.getUserDto().getBaseId());
                }
            }
        }

    }
}
